﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace Quail.Silverlight
{
    /// <summary>
    /// The silveright calendar control
    /// </summary>
    public class SlvCalendar : SlvControl
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SlvCalendar"/> class.
        /// </summary>
        public SlvCalendar()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SlvCalendar"/> class.
        /// </summary>
        /// <param name="container">The container for the control.</param>
        /// <param name="selector">The selector.</param>
        public SlvCalendar(SlvControlContainer container, string selector)
            : base(container, selector)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SlvCalendar"/> class.
        /// </summary>
        /// <param name="control">The control.</param>
        public SlvCalendar(SlvControl control)
            : base(control)
        {
        }

        /// <summary>
        /// Gets or sets the visual start time
        /// </summary>
        public DateTime VisualStartTime
        {
            get
            {
                return ConvertString(GetPropertyValue("VisualStartTime"));
            }

            set
            {
                SetPropertyValue("VisualStartTime", value.ToString());
            }
        }

        /// <summary>
        /// Gets or sets the selected date
        /// </summary>
        public DateTime SelectedDateTime
        {
            get
            {
                return ConvertString(GetPropertyValue("SelectedDateTime"));
            }

            set
            {
                SetPropertyValue("SelectedDateTime", value.ToString());
            }
        }

        /// <summary>
        /// Gets the list of appointments currently selected (as XML)
        /// </summary>
        public AppointmentCollection Appointments
        {
            get
            {
                var xml = GetPropertyValue("Appointments");
                var dom = new XmlDocument();
                dom.LoadXml(xml);
                var result = new AppointmentCollection(dom);
                return result;
            }
        }

        /// <summary>
        /// Opens the EditMailing window for a new appointment using the currently selected date
        /// </summary>
        public void OpenNewAppointment()
        {
            CallMethod("DoubleClick");
        }

        /// <summary>
        /// Opens the EditMailing window for the given appointment
        /// </summary>
        /// <param name="appointment">The appointment to open</param>
        public void OpenAppointment(Appointment appointment)
        {
            CallMethod("EditAppointment", appointment.Id.ToString());
        }

        private static DateTime ConvertString(string str)
        {
            // Sun Oct 18 2009 00:00:00 GMT-0400 (Eastern Daylight Time)
            return DateTime.ParseExact(str.Substring(0, 25) + str.Substring(28, 5), "ddd MMM dd yyyy hh:mm:ss K", System.Globalization.CultureInfo.InvariantCulture);
        }

        public class AppointmentCollection : List<Appointment>
        {
            public AppointmentCollection()
            {
            }
            
            public AppointmentCollection(XmlDocument xml)
            {
                var root = xml.DocumentElement;
                StartDate = DateTime.Parse(root.Attributes["StartDate"].Value);
                EndDate = DateTime.Parse(root.Attributes["EndDate"].Value);
                foreach (XmlNode node in root.ChildNodes)
                {
                    var appointment = new Appointment(node);
                    this.Add(appointment);
                }
            }
            
            public DateTime StartDate { get; set; }

            public DateTime EndDate { get; set; }
        }
        
        public class Appointment
        {
            public Appointment(XmlNode node)
            {
                Id = new Guid(node.Attributes["ID"].Value);
                Label = GetAttributeStringValue(node, "Label");
                Body = GetAttributeStringValue(node, "Body");
                IsRecurring = bool.Parse(node.Attributes["IsRecurring"].Value);
                Subject = GetAttributeStringValue(node, "Subject");
                Start = DateTime.Parse(node.Attributes["Start"].Value);
                End = DateTime.Parse(node.Attributes["End"].Value);
                Duration = TimeSpan.Parse(node.Attributes["Duration"].Value);
            }
            
            public Guid Id { get; set; }

            public string Label { get; set; }

            public string Body { get; set; }

            public bool IsRecurring { get; set; }
            
            public string Subject { get; set; }
            
            public DateTime Start { get; set; }
            
            public DateTime End { get; set; }
            
            public TimeSpan Duration { get; set; }

            private static string GetAttributeStringValue(XmlNode node, string name)
            {
                var attribute = node.Attributes[name];
                return (attribute != null) ? attribute.Value : null;
            }

            public override bool Equals(object obj)
            {
                var other = obj as Appointment;
                if (other == null)
                    return false;
                return Id == other.Id;
            }

            public override int GetHashCode()
            {
                return Id.GetHashCode();
            }
        }
    }
}
